Skip to content

feat: replace device flow with localhost callback auth#124

Merged
tim-thacker-nullify merged 8 commits intofeat/cli-mcp-polishfrom
feat/localhost-callback-auth
Feb 24, 2026
Merged

feat: replace device flow with localhost callback auth#124
tim-thacker-nullify merged 8 commits intofeat/cli-mcp-polishfrom
feat/localhost-callback-auth

Conversation

@tim-thacker-nullify
Copy link
Copy Markdown
Member

Summary

  • Rewrite Login() to use localhost callback instead of device code polling: starts local HTTP server on random port, opens browser to Cognito, waits for redirect callback, fetches tokens from backend
  • All HTTP calls use http.NewRequestWithContext for proper context propagation
  • All auth functions include tracer spans for observability
  • Simplify get_token.go to delegate stored credential lookup to auth.GetValidToken()

Test plan

  • Build CLI: go build ./cmd/cli
  • Run ./nullify auth login --host api.dev.nullify.ai — browser opens, authenticate, CLI shows "Authenticated successfully!" instantly
  • Run nullify auth status — shows authenticated with expiry
  • Run nullify auth token — prints valid token
  • Test timeout: start login, don't authenticate, verify 10-minute timeout message

🤖 Generated with Claude Code

tim-thacker-nullify and others added 8 commits February 24, 2026 15:53
Rewrite login flow: CLI starts a localhost HTTP server, opens browser
to Cognito, receives callback with session ID, fetches tokens from
backend. No more code confirmation or polling delay.

- Replace DeviceFlowLogin() with Login() using localhost callback
- Use http.NewRequestWithContext for proper context propagation
- Add tracer spans to all auth functions
- Simplify get_token.go to delegate to auth.GetValidToken()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Verify received session_id matches expected one (CSRF protection)
- Use sync.Once to guard against duplicate callback invocations
- Add ctx.Done() case to select for proper Ctrl+C cancellation
- Improve success HTML with checkmark SVG
- Create session before starting server to have expected session ID

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, a second callback to the CLI localhost server after sync.Once
would return an empty response. Now it returns the success HTML page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap login context with signal.NotifyContext so Ctrl+C triggers the
ctx.Done() select case, printing "authentication cancelled" cleanly
instead of an abrupt process termination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace go-arg-based main.go with cobra command structure
- Remove go-arg struct tags from DAST and auth models
- Add HTTP client timeout to NullifyClient
- Add generate-api Makefile target

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change ./cmd/cli/... to ./cmd/cli since the cobra cmd subpackage
is not a separate binary target.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tim-thacker-nullify tim-thacker-nullify added the minor Minor version updates (features) label Feb 24, 2026
@tim-thacker-nullify tim-thacker-nullify merged commit afea315 into feat/cli-mcp-polish Feb 24, 2026
2 of 3 checks passed
@tim-thacker-nullify tim-thacker-nullify deleted the feat/localhost-callback-auth branch February 24, 2026 07:13
tim-thacker-nullify added a commit that referenced this pull request Feb 24, 2026
* feat: add output formatting, enhanced MCP tools, unit tests, and security fixes

- Add output formatting package (json/yaml/table) with --output flag support
- Update code generator to use output.Print() for all 326 generated commands
- Add composite MCP tools: get_security_posture_summary, get_findings_for_repo
- Add triage tools for SCA, secrets, and DAST findings
- Add --repo flag to MCP serve with git remote auto-detection
- Add unit tests for auth, MCP server helpers, output formatters, API client
- Fix: config file permissions changed from 0644 to 0600
- Fix: add HTTP status code check in device token polling
- Fix: show manual URL message when browser can't be opened
- Fix: remove token value from debug log output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: replace device flow with localhost callback auth (#124)

* feat: replace device code polling with localhost callback auth

Rewrite login flow: CLI starts a localhost HTTP server, opens browser
to Cognito, receives callback with session ID, fetches tokens from
backend. No more code confirmation or polling delay.

- Replace DeviceFlowLogin() with Login() using localhost callback
- Use http.NewRequestWithContext for proper context propagation
- Add tracer spans to all auth functions
- Simplify get_token.go to delegate to auth.GetValidToken()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden login with CSRF check, duplicate guard, and ctx cancellation

- Verify received session_id matches expected one (CSRF protection)
- Use sync.Once to guard against duplicate callback invocations
- Add ctx.Done() case to select for proper Ctrl+C cancellation
- Improve success HTML with checkmark SVG
- Create session before starting server to have expected session ID

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix duplicate callback handling: serve success page on repeated requests

Previously, a second callback to the CLI localhost server after sync.Once
would return an empty response. Now it returns the success HTML page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add signal handling for graceful Ctrl+C during login

Wrap login context with signal.NotifyContext so Ctrl+C triggers the
ctx.Done() select case, printing "authentication cancelled" cleanly
instead of an abrupt process termination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix go.mod: run go mod tidy to sync dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Migrate CLI from go-arg to cobra and clean up struct tags

- Replace go-arg-based main.go with cobra command structure
- Remove go-arg struct tags from DAST and auth models
- Add HTTP client timeout to NullifyClient
- Add generate-api Makefile target

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix Makefile build target for cobra package structure

Change ./cmd/cli/... to ./cmd/cli since the cobra cmd subpackage
is not a separate binary target.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix lint errors: errcheck and gofmt issues

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
github-merge-queue Bot pushed a commit that referenced this pull request Feb 24, 2026
* feat: add GoReleaser, install script, and distribution channels

Replace manual cross-compilation and release workflow with GoReleaser
for consistent artifact naming, checksums, and automatic publishing to
Homebrew tap and Scoop bucket. Add a curl|sh install script for easy
Linux/macOS installation. Rewrite README installation section with
platform-specific one-liners and fix badge links.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: remove Homebrew tap, Scoop bucket, and extra token config

Keep everything self-contained in this repo — no separate tap/bucket
repos or additional token secrets needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restore original release trigger and versioning flow

Keep push-to-main trigger and PR-label-based semver calculation via
release-version action. GoReleaser runs after the version is calculated
and the tag is created.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add output formatting, MCP tools, tests, and security fixes (#123)

* feat: add output formatting, enhanced MCP tools, unit tests, and security fixes

- Add output formatting package (json/yaml/table) with --output flag support
- Update code generator to use output.Print() for all 326 generated commands
- Add composite MCP tools: get_security_posture_summary, get_findings_for_repo
- Add triage tools for SCA, secrets, and DAST findings
- Add --repo flag to MCP serve with git remote auto-detection
- Add unit tests for auth, MCP server helpers, output formatters, API client
- Fix: config file permissions changed from 0644 to 0600
- Fix: add HTTP status code check in device token polling
- Fix: show manual URL message when browser can't be opened
- Fix: remove token value from debug log output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: replace device flow with localhost callback auth (#124)

* feat: replace device code polling with localhost callback auth

Rewrite login flow: CLI starts a localhost HTTP server, opens browser
to Cognito, receives callback with session ID, fetches tokens from
backend. No more code confirmation or polling delay.

- Replace DeviceFlowLogin() with Login() using localhost callback
- Use http.NewRequestWithContext for proper context propagation
- Add tracer spans to all auth functions
- Simplify get_token.go to delegate to auth.GetValidToken()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden login with CSRF check, duplicate guard, and ctx cancellation

- Verify received session_id matches expected one (CSRF protection)
- Use sync.Once to guard against duplicate callback invocations
- Add ctx.Done() case to select for proper Ctrl+C cancellation
- Improve success HTML with checkmark SVG
- Create session before starting server to have expected session ID

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix duplicate callback handling: serve success page on repeated requests

Previously, a second callback to the CLI localhost server after sync.Once
would return an empty response. Now it returns the success HTML page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add signal handling for graceful Ctrl+C during login

Wrap login context with signal.NotifyContext so Ctrl+C triggers the
ctx.Done() select case, printing "authentication cancelled" cleanly
instead of an abrupt process termination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix go.mod: run go mod tidy to sync dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Migrate CLI from go-arg to cobra and clean up struct tags

- Replace go-arg-based main.go with cobra command structure
- Remove go-arg struct tags from DAST and auth models
- Add HTTP client timeout to NullifyClient
- Add generate-api Makefile target

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix Makefile build target for cobra package structure

Change ./cmd/cli/... to ./cmd/cli since the cobra cmd subpackage
is not a separate binary target.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix lint errors: errcheck and gofmt issues

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address security review findings

- Fail install if no checksum tool available instead of silently bypassing
- Create config dir with 0700 permissions, config file with 0600
- Sanitize host value before JSON interpolation
- URL-encode refresh token in query parameter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor Minor version updates (features)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant